package com.itheima.mp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.itheima.mp.domain.dto.PageDTO;
import com.itheima.mp.domain.po.Address;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.query.UserQuery;
import com.itheima.mp.domain.vo.AddressVO;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.enums.UserStatus;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * UserServiceImpl
 * </p>
 *
 * @author flyduck
 * @since 2025/2/25
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements IUserService {

    @Override
    @Transactional
    public void reduceBalanceById(Long id, Integer money) {
        //查询用户
        User user = this.getById(id);

        //校验状态
        if (user == null || user.getStatus() == UserStatus.FREEZE) {
            throw new RuntimeException("用户状态异常！");
        }

        //校验余额充足
        if (user.getBalance() < money) {
            throw new RuntimeException("用户余额不足！");
        }

        //扣减
        int remainBalance = user.getBalance() - money;
        this.lambdaUpdate()
                .set(User::getBalance,remainBalance)
                .set(remainBalance == 0,User::getStatus,UserStatus.FREEZE)//金额=0，设置用户冻结
                .eq(User::getId,id)
                .eq(User::getBalance,user.getBalance())//并发更新问题
                .update();
    }

    @Override
    public List<User> queryUsers(UserQuery userQuery) {
        return this.lambdaQuery()
                .like(userQuery.getName() != null,User::getUsername,userQuery.getName())
                .eq(userQuery.getStatus() != null,User::getStatus,userQuery.getStatus())
                .gt(userQuery.getMinBalance() != null,User::getBalance,userQuery.getMinBalance())
                .lt(userQuery.getMaxBalance() != null,User::getBalance,userQuery.getMaxBalance())
                .list();
    }

    @Override
    public UserVO queryUserAndAddressById(Long id) {
        //查用户
        User user = this.getById(id);

        if (user == null || user.getStatus() == UserStatus.FREEZE) {
            throw new RuntimeException("用户状态异常！");
        }

        //查地址
        List<Address> addressList = Db.lambdaQuery(Address.class)
                .eq(Address::getUserId, id)
                .list();

        UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);

        if(CollUtil.isNotEmpty(addressList)){
            List<AddressVO> addressVOList = BeanUtil.copyToList(addressList, AddressVO.class);
            userVO.setAddressVOList(addressVOList);
        }
        return userVO;
    }

    @Override
    public List<UserVO> queryUserAndAddressByIds(List<Long> ids) {
        //查用户
        List<User> userList = this.listByIds(ids);

        if(CollUtil.isEmpty(userList)){
            return Collections.emptyList();
        }

        //查地址
        List<Long> userIdList = userList.stream().map(User::getId).collect(Collectors.toList());
        List<Address> addressList = Db.lambdaQuery(Address.class)
                .in(Address::getUserId, userIdList)
                .list();
        List<AddressVO> addressVOList = BeanUtil.copyToList(addressList, AddressVO.class);
        Map<Long, List<AddressVO>> collect = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));

        //转vo返回
        List<UserVO> userVOList = new ArrayList<>(userList.size());
        for (User user : userList) {
            UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
            userVO.setAddressVOList(collect.get(user.getId()));
            userVOList.add(userVO);
        }
        return userVOList;
    }

    @Override
    public PageDTO<UserVO> queryUsersPage(UserQuery userQuery) {
        //构建分页条件和排序条件
        Page<User> page = userQuery.toMpPageDefaultOrderByUpdateTime();

        //分页查询
        Page<User> userPage = lambdaQuery()
                .like(userQuery.getName() != null, User::getUsername, userQuery.getName())
                .eq(userQuery.getStatus() != null, User::getStatus, userQuery.getStatus())
                .gt(userQuery.getMinBalance() != null, User::getBalance, userQuery.getMinBalance())
                .lt(userQuery.getMaxBalance() != null, User::getBalance, userQuery.getMaxBalance())
                .page(page);

        //封装vo结果
        //如果拷贝字段名称不一致可以自定义
//        return PageDTO.of(userPage,user -> {
//            UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
//            //拷贝其他属性
//            return userVO;
//        });
        return PageDTO.of(userPage,UserVO.class);
    }
}
